﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using Ninject.Contrib.Configuration;
using NUtilities.IO;
using Ninject.Modules;
using Ninject;
using CustomWeapons;

namespace NinjectTest
{
  public interface IWeapon
  {
    void Hit(string target);
  }

  class Sword : IWeapon
  {
    public void Hit(string target)
    {
      Console.WriteLine("Chopped {0} clean in half", target);
    }
  }

  class Shuriken : IWeapon
  {
    public void Hit(string target)
    {
      Console.WriteLine("Pierced {0}'s armor", target);
    }
  }

  class Samurai
  {
    private IKernel _kernel;
    private IWeapon _weapon;
    
    [Inject]
    public Samurai(IKernel kernel)
    {
      _kernel = kernel;
    }

    public void Arm(string weapon)
    {
      _weapon = _kernel.Get<IWeapon>(weapon);
    }

    public void Attack(string target)
    {
      if (_weapon != null)
      {
        _weapon.Hit(target);
      }
      else
      {
        Console.WriteLine("Droped the weapon! {0} might escape!", target);
      }
    }
  }

  // NOT USED
  class WarriorModule : NinjectModule 
  {
    public override void Load() {
      this.Bind<IWeapon>().To<Sword>();
      this.Bind<Samurai>().ToSelf();
      
    }
  }
  
  // NOT USED
  class WeaponsModule : NinjectModule
  {
    private readonly string _weaponType;

    public WeaponsModule(string weaponType)
    {
      _weaponType = weaponType;
    }

    public override void Load()
    {
      if (_weaponType == "Melee")
      {
        Bind<IWeapon>().To<Sword>().Named("Sword");
        Bind<IWeapon>().To<Pike>().Named("Pike");
      }
      else
      {
        Bind<IWeapon>().To<Shuriken>().Named("Shuriken");
        Bind<IWeapon>().To<Star>().Named("Star");
      }

      Bind<Samurai>().ToSelf();
    }
  }

  class Program
  {
    public static void Main()
    {
      #region Generate BindingConfiguration
      //BindingConfiguration configuration = new BindingConfiguration();
      //configuration.Bindings = new List<Binding>
      //{
      //  new Binding 
      //  { 
      //    Interface = "NinjectTest.IWeapon", 
      //    Implementation = "NinjectTest.Shuriken",
      //    Name = "Shuriken",
      //  },
      //  new Binding 
      //  { 
      //    Interface = "NinjectTest.IWeapon", 
      //    Implementation = "NinjectTest.Sword",
      //    Name = "Sword",
      //  },
      //  new Binding 
      //  { 
      //    Interface = "NinjectTest.Samurai", 
      //    Implementation = "self",
      //  },
      //};

      //IOUtility.Write<BindingConfiguration>(configuration, "..\\..\\BindingConfiguration.xml", false);
      #endregion

      //BindingConfiguration configuration = IOUtility.Read<BindingConfiguration>("..\\..\\BindingConfiguration.xml", false);

      //IKernel kernel = new StandardKernel(new ConfigurationModule(configuration));
      WeaponsModule module = new WeaponsModule("Melee");
      //WarriorModule module = new WarriorModule();
      IKernel kernel = new StandardKernel(module);
      //kernel.Load();
      
      Samurai warrior = kernel.Get<Samurai>();

      #region Choose your weapon...
      Console.WriteLine("Choose your weapon...");

      //var names = from binding in configuration.Bindings
      //            where binding.Interface.Contains("Weapon")
      //            orderby binding.Name
      //            select binding.Name;
      //foreach (string name in names)
      //{
      //  Console.WriteLine("  * " + name);
      //}
      
      Console.WriteLine("?");
      string weapon = Console.ReadLine();
      #endregion

      warrior.Arm(weapon);
      warrior.Attack("the evildoers");

      Console.ReadKey();
    }
  }

}
